package me.learningandroid.ch1_7;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;

public class Threading {
    /**
     * Runnable示例，Java最原始的线程模型
     * @throws InterruptedException
     */
    private void simpleThreadNoReturn() throws InterruptedException {
        // Runnable代表了异步代码段，代码段没有返回值
        // Runnable本身不启动线程
        // Thread启动线程并异步执行Runnable里的代码
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello Runnable Thread");
            }
        });
        thread.start(); // 开始线程
        thread.join(); // 等待线程结束，返回当前线程
    }

    /**
     * Callable示例，Java最原始的线程模型
     * @throws InterruptedException
     * @throws ExecutionException
     */
    private void simpleThreadWithReturn() throws InterruptedException, ExecutionException {
        // Callable也代表了异步代码段，代码段有返回值
        // FutureTask将Callable包装为Runnable，用以提交到Thread中
        // Thread启动线程并异步执行Callable里的代码，结果被FutureTask保存
        FutureTask future = new FutureTask<>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(1000);
                return "Hello Callable Thread";
            }
        });
        Thread thread = new Thread(future);
        thread.start(); // 开始线程
        thread.join(); // 等待线程结束，返回当前线程
        System.out.println(future.get()); // 获取FutureTask中的结果
    }

    /**
     * ExecutorService示例。ExecutorService提供了线程池管理，是实际开发中常用的线程框架
     * @throws InterruptedException
     * @throws ExecutionException
     */
    private void executorFramework() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newFixedThreadPool(5); // ExecutionService是多线程编程中较高抽象级的服务，提供线程管理，任务管理，阻塞队列等。
        Future future1 = executorService.submit(() -> "Hello Executor 1"); // 提交Callable 任务
        Future future2 = executorService.submit(() -> System.out.println("Hello Executor 2")); // 提交Runnable 任务
        executorService.awaitTermination(1, TimeUnit.SECONDS); // 等待所有任务结束
        System.out.println(future1.get());
        System.out.println(future2.get());
    }
    
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        new Threading().simpleThreadNoReturn();
        new Threading().simpleThreadWithReturn();
        new Threading().executorFramework();
    }

    
}
